import { Modal, notification } from "ant-design-vue";
import { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";

import Request from "@common/js/request1";
import {
  HEADER_TOKEN_KEY,
  HEADER_TOKEN_PREFIX,
  TOKEN_SESSION_KEY,
} from "@/config/tokenConstant";

import _isEmpty from "lodash/isEmpty";
import { HTTP_RRESPONSE_CODE } from "@/common/dict";

type BaseResponseVO<T> = {
  status: number;
  msg: string;
  data: T;
};

export interface CustomRequestConfig extends AxiosRequestConfig {
  errorHandler?: boolean;
}

export default class Service {
  private requestInstance: Request | null;

  private isShownErrorAlert: boolean = false;

  constructor() {
    this.requestInstance = new Request({
      baseURL: "/api",
      interceptors: {
        requestInterceptor: (config) => {
          const authToken = this.getToken();
          if (authToken) {
            // 注入token
            config.headers![
              HEADER_TOKEN_KEY
            ] = `${HEADER_TOKEN_PREFIX}${authToken}`;
          }
          return config;
        },
        responseInterceptor: (responseConfig) => {
          // TODO: 判断有无返回token,有token就存入localstorage
          return responseConfig;
        },
      },
    });
  }

  static instance: Service | null = null;

  static getInstance(): Service {
    if (!this.instance) {
      this.instance = new Service();
    }
    return this.instance;
  }

  private getToken(): string | null {
    const result = window.localStorage.getItem(TOKEN_SESSION_KEY);
    return _isEmpty(result) ? "" : result;
  }

  private showErrorAlert(errorMsg: string): void {
    this.isShownErrorAlert = true;
    // 全局处理错误信息
    Modal.confirm({
      title: "温馨提示",
      content: errorMsg,
      okText: "确认",
      cancelText: "取消",
      onOk: () => {
        this.isShownErrorAlert = false;
      },
      onCancel: () => {
        this.isShownErrorAlert = false;
      },
    });
  }

  request<T>(config: CustomRequestConfig): Promise<BaseResponseVO<T>> {
    return new Promise((resolve, reject) => {
      this.requestInstance
        ?.request<BaseResponseVO<T>>(config)
        .then((res: BaseResponseVO<T>) => {
          if (res.status === HTTP_RRESPONSE_CODE.SUCCESS) {
            resolve(res);
          } else {
            // 业务错误
            console.log("业务错误");
            if (!config.errorHandler && !this.isShownErrorAlert) {
              this.showErrorAlert(res.msg);
            }
            reject(res);
          }
        })
        .catch((err: any) => {
          // console.log("逻辑错误");
          if (!config.errorHandler) {
            // 全局处理错误信息
            if (err instanceof AxiosError) {
              this.showErrorAlert(err.message);
            }
          }
          reject(err);
        });
    });
  }
}
